package se.webbzon.boltzmann.game.sequence.builder.event;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;

import se.webbzon.boltzmann.game.event.GameEventEnum;
import se.webbzon.boltzmann.game.sequence.builder.SequenceBuilder;
import se.webbzon.boltzmann.game.sequence.builder.SequenceRowDeflation;
import se.webbzon.oschi01.friendly.Friendly;

public class GameEventRowDeflation implements SequenceRowDeflation {
	
	private GameEventEnum gameEvent;
	
	private String[] arguments;

	/*============================================================
	Constructors
	============================================================*/
	
	public GameEventRowDeflation() {};
	
	public GameEventRowDeflation(GameEventRow row) {
		gameEvent = row.getGameEvent();
		arguments = row.getArguments();
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	@Override public void inflate(ByteBuffer buff) {
		// Read from buffer
		gameEvent = GameEventEnum.values()[buff.getInt()];
		final int args = buff.getShort();
		byte[][] argumentData = new byte[args][];
		for (int i = 0; i < args; i++) {
			final short size = buff.getShort();
			argumentData[i] = new byte[size];
			buff.get(argumentData[i], 0, size);
		}
		
		// Decode arguments
		arguments = new String[args];
		for (int i = 0; i < args; i++) {
			try {
				arguments[i] = new String(argumentData[i],"UTF-8");
			} catch (UnsupportedEncodingException e) {
				arguments[i] = "";
			}
		}
	}

	@Override public ByteBuffer deflate(int allocate) {
		final int args;
		final byte[][] argumentData;
		if (arguments == null) {
			argumentData = new byte[0][];
			args = 0;
		} else {
			args = arguments.length;
			argumentData = new byte[args][];
		}
		
		// Encode arguments
		int size = 2 + 2 * args;
		for (int i = 0; i < args; i++) {
			try {
				argumentData[i] = arguments[i].getBytes("UTF-8");
				size += argumentData[i].length;
			} catch (UnsupportedEncodingException e) {
				argumentData[i] = new byte[0];
			}
		}
		
		ByteBuffer buff = ByteBuffer.allocate(allocate + 4 + size);
		
		// Write to buffer
		buff.putInt(gameEvent.ordinal());
		buff.putShort((short) args);
		for (int i = 0; i < args; i++) {
			buff.putShort((short) argumentData[i].length);
			buff.put(argumentData[i]);
		}
		
		return buff;
	}
	
	/*============================================================
	Friendly Methods
	============================================================*/
	
	@Friendly GameEventRow makeRow(SequenceBuilder sequenceBuilder) {
		return new GameEventRow(sequenceBuilder,gameEvent,arguments);
	}

}
